package org.beanutopia.function;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Nullable;
import com.google.common.base.Functions;

/**
 * @author ymeymann
 * @since Oct 30, 2007 11:53:10 PM
 */
public class FunctionPolicy<F,T> extends Policy<F, Function<? super F, ? extends T>> {
  
  public FunctionPolicy() {
    super(1);
  }

  public FunctionPolicy(int capacity) {
    super(capacity);
  }

  public Function<F,T> reduce() {
    if (size() > 0 && first().predicate().equals(PredicateComparator.IS_NULL)) {//is null safe
      return new Function<F,T>() {
        public T apply(@Nullable F from) {
          Function<? super F, ? extends T> f = FunctionPolicy.this.apply(from);
          return f.apply(from);
        }
      };
    } else {
      return new Function<F,T>() {
        public T apply(F from) {
          Function<? super F, ? extends T> f = FunctionPolicy.this.apply(from);
          return f == null ? null : f.apply(from); 
        }
      };
    }
  }

  @Override
  public FunctionPolicy<F,T> addRule(Predicate<? super F> condition, Function<? super F, ? extends T> action) {
    super.addRule(condition, action);
    return this;
  }

  @Override
  public FunctionPolicy<F,T> addRule(Function<? super F, ? extends T> defaultAction) {
    super.addRule(PredicateComparator.ALWAYS_TRUE, defaultAction);
    return this;
  }

  @Override
  public FunctionPolicy<F,T> addNullSafetyRule() {
    addRule(PredicateComparator.IS_NULL, Functions.<T>constant(null));
    return this;
  }

}
